﻿using System.Linq.Expressions;
using RpcHelper;
using SqlSugar;

namespace SqlSugarHelper.Repository
{
    internal class LocalQueue<T> : ISqlQueue<T> where T : class, new()
    {
        private SqlSugarProvider _DbClient;
        public LocalQueue(SqlSugarProvider client)
        {
            _DbClient = client;
        }


        public void Insert(T item)
        {
            _DbClient.Insertable<T>(item).AddQueue();
        }

        public void Insert(T[] items)
        {
            _DbClient.Insertable<T>(items).AddQueue();
        }
        public void Delete(Expression<Func<T, bool>> filter)
        {
            this._DbClient.Deleteable<T>().Where(filter).AddQueue();
        }

        public void Delete<Other>(Expression<Func<T, Other, bool>> filter) where Other : class, new()
        {
            this._DbClient.Deleteable<T>().Where(p => SqlFunc.Subqueryable<Other>().Where(filter).Any()).AddQueue();
        }
        public void Update(T[] datas, params string[] ignoreColumn)
        {
            if (ignoreColumn.IsNull())
            {
                _DbClient.Updateable(datas).AddQueue();
                return;
            }
            _DbClient.Updateable(datas).IgnoreColumns(ignoreColumn).AddQueue();
        }
        public void Update<Set>(Set set, Expression<Func<T, bool>> filter)
        {
            _DbClient.Updateable<T>(set).Where(filter).AddQueue();
        }
        public void UpdateOnly(T[] datas, Expression<Func<T, object>> setCol)
        {
            _DbClient.Updateable(datas).UpdateColumns(setCol).AddQueue();
        }


        public void Update(T data, string[] column)
        {
            _DbClient.Updateable(data).UpdateColumns(column).AddQueue();
        }
        public void Update(Expression<Func<T, T>> columns, Expression<Func<T, bool>> filter)
        {
            _DbClient.Updateable<T>().SetColumns(columns).Where(filter).AddQueue();
        }
        public IUpdateable<T> Update(Expression<Func<T, bool>> filter)
        {
            return _DbClient.Updateable<T>().Where(filter);
        }
        public bool Update<Set>(T source, Set set)
        {
            string[] cols = source.Merge(set);
            if (cols.Length == 0)
            {
                return false;
            }
            this.Update(source, cols);
            return true;
        }

        public bool Update(T source, T set)
        {
            string[] cols = source.Merge<T>(set);
            if (cols.Length == 0)
            {
                return false;
            }
            this.Update(source, cols);
            return true;
        }
        public int Submit(bool isTran = true)
        {
            return _DbClient.SaveQueues(isTran);
        }

     
        public void Delete<Table>(Expression<Func<Table, bool>> filter) where Table : class, new()
        {
            this._DbClient.Deleteable<Table>().Where(filter).AddQueue();
        }

        public void Delete<Table, Other>(Expression<Func<Table, Other, bool>> filter)
            where Table : class, new()
            where Other : class, new()
        {
            this._DbClient.Deleteable<Table>().Where(p => SqlFunc.Subqueryable<Other>().Where(filter).Any()).AddQueue();
        }

        public void Insert<Table>(Table item) where Table : class, new()
        {
            _DbClient.Insertable<Table>(item).AddQueue();
        }

        public void Insert<Table>(Table[] items) where Table : class, new()
        {
            _DbClient.Insertable<Table>(items).AddQueue();
        }
        public void Update(T[] datas, Expression<Func<T, object>> filter) 
        {
            _DbClient.Updateable(datas).WhereColumns(filter).AddQueue();
        }
        public void Update<Table>(Table[] datas, params string[] ignoreColumn) where Table : class, new()
        {
            if (ignoreColumn.IsNull())
            {
                _DbClient.Updateable<Table>(datas).AddQueue();
                return;
            }
            _DbClient.Updateable<Table>(datas).IgnoreColumns(ignoreColumn).AddQueue();
        }
        public void Update<Table,Set>(Set set, Expression<Func<Table, bool>> filter) where Table : class, new()
        {
            _DbClient.Updateable<Table>(set).Where(filter).AddQueue();
        }
        public void Update<Table>(Table data, string[] column) where Table : class, new()
        {
            _DbClient.Updateable<Table>(data).UpdateColumns(column).AddQueue();
        }
        public void Update<Table>(Expression<Func<Table, Table>> columns, Expression<Func<Table, bool>> filter) where Table : class, new()
        {
            _DbClient.Updateable<Table>().SetColumns(columns).Where(filter).AddQueue();
        }
        public bool Update<Table,Set>(Table source, Set set) where Table : class, new()
        {
            string[] cols = source.Merge(set);
            if (cols.Length == 0)
            {
                return false;
            }
            this.Update<Table>(source, cols);
            return true;
        }

        public bool Update<Table>(Table source, Table set) where Table : class, new()
        {
            string[] cols = source.Merge<Table>(set);
            if (cols.Length == 0)
            {
                return false;
            }
            this.Update<Table>(source, cols);
            return true;
        }
    }
}
